package com.soonfor.evaluate.http.httptools;

import android.content.Context;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import com.estronger.shopmanage.base.MyApplication;
import com.estronger.shopmanage.bean.ReturnMsgEntity;
import com.estronger.shopmanage.utils.DataTools;
import com.estronger.shopmanage.utils.JsonUtil;
import com.estronger.shopmanage.utils.Toast;
import com.google.gson.Gson;
import com.lidroid.xutils.util.LogUtils;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.PersistentCookieStore;
import com.orhanobut.hawk.Hawk;
import com.soonfor.evaluate.base.EvalHeadBean;
import com.soonfor.evaluate.bean.FileUploadBean;
import com.soonfor.evaluate.tools.CommonUtils;
import com.soonfor.evaluate.tools.JsonAnalysisUtils;
import com.soonfor.evaluate.tools.UserInfo;

import okhttp3.*;
import org.apache.http.Header;
import org.apache.http.entity.ByteArrayEntity;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.jesse.nativelogger.NLogger;

public class AsyncUtils {


    public interface NetWorkListenner{
        void onSuccess(Object object);
        void onFailure(Exception e);
    }

    static ReturnMsgEntity resultEntity = null;
    static boolean isAnalySuccess = true;//是否解析成功

    public interface AsyncCallback {
        void success(int requestCode, String object);

        void fail(int requestCode, int statusCode, String data, String msg);
    }

    public interface AsyncCallback2 {
        void success(String type, int requestCode, String data);

        void onProgress(String type, int requestCode, int count);

        void fail(String type, int requestCode, int statusCode, String msg);
    }

    public interface UploadFileCallback {
        /**
         * @param requestCode
         * @param filePath    上传的附件的原路径
         * @param uploadBean  上传成功后的返回实体对象
         */
        void success(int requestCode, String filePath, FileUploadBean uploadBean);

        void fail(int requestCode, String msg);
    }


    /**
     * 提交专用
     */
    public static void postToSubmit(Context context, final String url, final RequestParams params,
                                    final int requestCode, final boolean isNeedAnalysis, final AsyncCallback callback) {
        AsyncHttpClient client = new AsyncHttpClient();
        PersistentCookieStore myCookieStore = new PersistentCookieStore(context);
        client.setCookieStore(myCookieStore);
        client.setTimeout(60 * 1000);
        String fullUrl = MyApplication.getApplication().getSERVER_URL() + url;
        client.post(fullUrl, params, new AsyncHttpResponseHandler() {
            @Override
            public void onSuccess(int i, Header[] headers, byte[] bytes) {
                String result = new String(bytes);
                callback.success(requestCode, result);
            }

            @Override
            public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
                String result = "";
                String Errmsg = "请求出错";
                if (bytes != null) {
                    result = new String(bytes);
                    JSONObject object = null;
                    try {
                        object = new JSONObject(result);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    if (object != null) Errmsg = object.toString();
                } else if (throwable != null) {
                    Errmsg = "网络异常, 请检查网络";//throwable.toString();
                }
                if (Errmsg == null || Errmsg.equals("")) {
                    callback.fail(requestCode, -1, Errmsg, "网络错误");
                } else {
                    callback.fail(requestCode, -1, Errmsg, getFailure("请求出错", Errmsg));
                }
            }
        });
    }


    /**
     * 参数 表单
     *
     * @param context
     * @param url
     * @param bodyParams
     * @param requestCode
     * @param isNeedAnalysis 是否需要解析
     * @param callback
     */
    public static void post(final Context context, final String url, final Map<String, String> bodyParams,
                            final int requestCode, final boolean isNeedAnalysis, final AsyncCallback callback) {
        if (!NetUtils.isConnectInternet(context)) {
            NetUtils.IfNetOff_OpenSetUI(context);
            String emsg = "您的WLAN和移动网络均未连接！";
            callback.fail(requestCode, -1, "", emsg);
        } else {
            resultEntity = null;
            isAnalySuccess = true;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //SoonforApplication.apiTime = System.currentTimeMillis();
                        if (MyApplication.client == null) {
                            MyApplication.client = new OkHttpClient.Builder()
                                    .writeTimeout(20, TimeUnit.SECONDS)
                                    .readTimeout(20, TimeUnit.SECONDS)
                                    .connectTimeout(20, TimeUnit.SECONDS)
                                    .build();
                        }
                        String fullUrl = MyApplication.getApplication().getSERVER_URL() + url;
                        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
                        addParams(bodyParams, builder);
                        RequestBody body = builder.build();
                        final Request request = new Request.Builder().url(fullUrl)
                                .post(body)
                                .build();
                        final Call call = MyApplication.client.newCall(request);
                        call.enqueue(new Callback() {
                            @Override
                            public void onFailure(Call call, final IOException e) {
                                new Handler(context.getMainLooper()).post(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
                                            String result = e.getMessage();
                                            if (result == null || result.equals("")) {
                                                callback.fail(requestCode, -1, result, "网络错误");
                                            } else {
                                                if (bodyParams != null && bodyParams.containsKey("sf_action"))
                                                    callback.fail(requestCode, -1, result, getFailure(bodyParams.get("sf_action"), result));
                                                else
                                                    callback.fail(requestCode, -1, result, getFailure("请求出错", result));
                                            }
                                        } catch (Exception e) {
                                        }
                                    }
                                });
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                final String result = response.body().string();
                                if (isNeedAnalysis) {
                                    try {
                                        resultEntity = JsonUtil.getMsgEntity(result);
                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                        isAnalySuccess = false;
                                    }
                                    new Handler(context.getMainLooper()).post(new Runnable() {
                                        @Override
                                        public void run() {
                                            try {
                                                // 在这里执行你要想的操作 比如直接在这里更新ui或者调用回调在 在回调中更新ui
                                                if (resultEntity != null) {
                                                    if (resultEntity.getSuccess()) {
                                                        callback.success(requestCode, resultEntity.getDataJson());
                                                    } else {
                                                        if (resultEntity.getMsg() == null || resultEntity.getMsg().equals("")) {
                                                            callback.fail(requestCode, resultEntity.getMsgcode(), resultEntity.getDataJson(), "网络错误");
                                                        } else {
                                                            if (bodyParams != null && bodyParams.containsKey("sf_action"))
                                                                callback.fail(requestCode, -1, result, getFailure(bodyParams.get("sf_action"), resultEntity.getMsg()));
                                                            else
                                                                callback.fail(requestCode, -1, result, getFailure("请求出错", resultEntity.getMsg()));
                                                        }
                                                    }
                                                } else if (!isAnalySuccess) {
                                                    callback.success(requestCode, result);
                                                    isAnalySuccess = true;
                                                } else {
                                                    if (bodyParams != null && bodyParams.containsKey("sf_action"))
                                                        callback.fail(requestCode, -1, result, getFailure(bodyParams.get("sf_action"), result));
                                                    else
                                                        callback.fail(requestCode, -1, result, getFailure("请求出错", result));
                                                }
                                            } catch (Exception e) {
                                            }
                                        }
                                    });
                                } else {
                                    new Handler(context.getMainLooper()).post(new Runnable() {
                                        @Override
                                        public void run() {
                                            try {
                                                if (result == null) {
                                                    callback.fail(requestCode, -1, result, getFailure("数据为空", result));
                                                } else {
                                                    callback.success(requestCode, result);
                                                }
                                            } catch (Exception e) {
                                            }
                                        }
                                    });
                                }
                            }
                        });
                    } catch (Exception e) {
                    }
                }
            }).start();
        }
    }


    /**
     * 设置多参数
     *
     * @param params
     * @param builder
     */
    static void addParams(Map<String, String> params, MultipartBody.Builder builder) {
        if (params != null && !params.isEmpty()) {
            for (String key : params.keySet()) {
                builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + key.replaceAll("\\[\\d+\\]", "") + "\""), RequestBody.create(null, params.get(key)));
            }
        }
    }

    //post 请求 参数类型：json字符串
    public static void post(final Context context, final String url, final String jsonParams, final int requestCode, int outTime, final AsyncCallback callback) {
        AsyncHttpClient client = new AsyncHttpClient();
        PersistentCookieStore myCookieStore = new PersistentCookieStore(context);
        client.setCookieStore(myCookieStore);
        client.setTimeout(outTime * 1000);
//        setHeader(client, false);
        ByteArrayEntity entity = null;
        try {
            entity = new ByteArrayEntity(jsonParams.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        LogUtils.d("请求URL：" + UserInfo.HOST_STRING + url + "==>请求参数：" + jsonParams);//方便调试不需要删除，已开启debug模式才打印
        //http的post请求,调用下面的post请求
        client.post(context, UserInfo.HOST_STRING + url, entity, "application/json", new AsyncHttpResponseHandler() {
            @Override
            public void onSuccess(int i, Header[] headers, byte[] bytes) {
                String result = new String(bytes);
                LogUtils.d("返回结果：" + result);//方便调试不需要删除，已开启debug模式才打印
                callback.success(requestCode, result);
            }

            @Override
            public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
                failResult(context, requestCode, callback, i, headers, bytes, throwable);
            }
        });
    }

    //失败
    private static void failResult(Context context, int requestCode, AsyncCallback callback, int i, Header[] headers, byte[] bytes, Throwable throwable) {
        if (!NetUtils.isConnectInternet(context)) {
            Toast.show(context, "网络异常！", Toast.LENGTH_SHORT);
            String result = new String(bytes);
            callback.fail(requestCode, i, result, getFailure("数据为空", result));
            return;
        }
        String result = new String(bytes);
        callback.fail(requestCode, i, result, getFailure("数据为空", result));
    }


    //设置请求头信息
    public static void setHeader(AsyncHttpClient client, boolean isNeedSetContentType) {
//        String uuid = Hawk.get(UserInfo.UUID, "");
//        if (!uuid.equals("")) {
//            client.addHeader("Authorization", "Bearer " + uuid);
//            if (isNeedSetContentType) {
//                client.addHeader("Content-Type", "application/x-www-form-urlencoded");
//            }
//        }
    }


    /**
     * 异步请求 get
     *
     * @param context
     * @param url
     * @param requestCode
     * @param callback
     */
    public static void get(final Context context, final String url, final int requestCode,
                           final AsyncCallback callback) {
        if (!NetUtils.isConnectInternet(context)) {
            NetUtils.IfNetOff_OpenSetUI(context);
            String emsg = "您的WLAN和移动网络均未连接！";
            callback.fail(requestCode, -1, "", emsg);
        } else {
            resultEntity = null;
            isAnalySuccess = true;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (MyApplication.client == null) {
                            MyApplication.client = new OkHttpClient.Builder()
                                    .writeTimeout(20, TimeUnit.SECONDS)
                                    .readTimeout(20, TimeUnit.SECONDS)
                                    .connectTimeout(20, TimeUnit.SECONDS)
                                    .build();
                        }
                        final String fullUrl = MyApplication.getApplication().getSERVER_URL() + url;
                        final okhttp3.Request request = new okhttp3.Request.Builder()
                                .url(fullUrl)
                                .get()
                                .build();
                        final Call call = MyApplication.client.newCall(request);
                        call.enqueue(new Callback() {
                            @Override
                            public void onFailure(Call call, final IOException e) {
                                new Handler(context.getMainLooper()).post(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
                                            String result = e.getMessage();
                                            if (result == null || request.equals("")) {
                                                callback.fail(requestCode, -1, result, "网络错误");
                                            } else {
                                                callback.fail(requestCode, -1, result, getFailure(fullUrl, result));
                                            }
                                        } catch (Exception e) {
                                        }

                                    }
                                });

                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                final String result = response.body().string();
                                try {
                                    resultEntity = JsonUtil.getMsgEntity(result);
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                    isAnalySuccess = false;
                                }
                                new Handler(context.getMainLooper()).post(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
                                            // 在这里执行你要想的操作 比如直接在这里更新ui或者调用回调在 在回调中更新ui
                                            if (resultEntity != null) {
                                                if (resultEntity.getSuccess()) {
                                                    callback.success(requestCode, resultEntity.getDataJson());
                                                } else {
                                                    if (resultEntity.getMsg() == null || resultEntity.getMsg().equals("")) {
                                                        callback.fail(requestCode, resultEntity.getMsgcode(), resultEntity.getDataJson(), "网络错误");
                                                    } else {
                                                        callback.fail(requestCode, resultEntity.getMsgcode(), resultEntity.getDataJson(), getFailure(fullUrl, resultEntity.getMsg()));
                                                    }
                                                }
                                            } else if (!isAnalySuccess) {
                                                callback.success(requestCode, result);
                                                isAnalySuccess = true;
                                            } else {
                                                callback.fail(requestCode, -1, result, getFailure(fullUrl, result));
                                            }
                                        } catch (Exception e) {
                                        }
                                    }
                                });
                            }
                        });
                    } catch (Exception e) {
                    }
                }
            }).start();
        }
    }

    /**
     * 上传文件到crm3.0或crm4.0
     *
     * @param context
     * @param url
     * @param params
     * @param requestCode
     * @param callback
     * @param crmVersion  0:soonfor.crm3.0//1:soonfor.crm4.0
     */
    public static void uploadFile(final Context context, final String url, final RequestParams params, final int requestCode, final String filePath,
                                  final UploadFileCallback callback, final int crmVersion) {
        AsyncHttpClient client = new AsyncHttpClient();
        PersistentCookieStore myCookieStore = new PersistentCookieStore(context);
        client.setCookieStore(myCookieStore);
        client.setTimeout(60 * 1000);
        setHeader(client, false);
        client.post(url, params, new AsyncHttpResponseHandler() {
            @Override
            public void onSuccess(int i, Header[] headers, byte[] bytes) {
                String result = new String(bytes);
                Gson gson = new Gson();
                FileUploadBean uploadBean = null;
                if (crmVersion == 0) {
                    try {
                        uploadBean = gson.fromJson(result, FileUploadBean.class);
                    } catch (Exception e) {
                    }
                    if (uploadBean != null) {
                        callback.success(requestCode, filePath, uploadBean);
                    } else {
                        callback.fail(requestCode, "上传失败");
                    }
                } else {
                    EvalHeadBean headBean = JsonAnalysisUtils.getHeadBean(result);
                    if (headBean.getMsgcode() == 0) {
                        try {
                            uploadBean = gson.fromJson(headBean.getData(), FileUploadBean.class);
                        } catch (Exception e) {
                        }
                        if (uploadBean != null) {
                            callback.success(requestCode, filePath, uploadBean);
                        }
                    } else {
                        callback.fail(requestCode, headBean.getData());
                    }
                }
            }

            @Override
            public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
                if (!NetUtils.isConnectInternet(context)) {
                    NetUtils.IfNetOff_OpenSetUI(context);
                    String emsg = "您的WLAN和移动网络均未连接！";
                    callback.fail(requestCode, emsg);
                } else {
                    Log.e("请求失败状态码", i + "");
                    String result = "";
                    JSONObject object = null;
                    if (bytes != null) {
                        result = new String(bytes);
                        try {
                            object = new JSONObject(result);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    callback.fail(requestCode, getFailure(url, result));
                }
            }
        });
    }

    public static void download(final String url, final String fileName, final String saveDir,
                                final NetWorkListenner listener) {


        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(120,TimeUnit.SECONDS)
                .readTimeout(120,TimeUnit.SECONDS)
                .connectionSpecs(Arrays.asList(
                        ConnectionSpec.MODERN_TLS,
                        ConnectionSpec.COMPATIBLE_TLS,
                        ConnectionSpec.CLEARTEXT)).build();
        final Request request = new Request.Builder()
                .url(url).build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //com.orhanobut.logger.Logger.e(e.getLocalizedMessage());
                listener.onFailure(e);
            }
            @Override
            public void onResponse(Call call, final Response response)
                    throws IOException {
                InputStream is = null;
                byte[] bytes=new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                try {
                    if (response.code() != 200){
                        listener.onFailure(new Exception());
                        return;
                    }
                    is = response.body().byteStream();//以字节流的形式拿回响应实体内容
                    String savePath = saveDir + "/" + fileName;
                    File file = new File(savePath);
                    fos = new FileOutputStream(file);

                    while ((len = is.read(bytes)) != -1) {
                        fos.write(bytes, 0, len);
                    }
                    fos.flush();
                    Map map = new HashMap();
                    map.put("path",file.getAbsolutePath());
                    listener.onSuccess(map);

                } catch (IOException e) {
                    listener.onFailure(e);
                    e.printStackTrace();
                } finally {
                    if (is != null) is.close();
                    if (fos != null) fos.close();
                }
            }
        });
    }

    public static void downloadFilesFromCrm(final Context context, final String url, final String jsonParams, final String filename, final int requestCode, AsyncCallback callback) {
        AsyncHttpClient client = new AsyncHttpClient();
        PersistentCookieStore myCookieStore = new PersistentCookieStore(context);
        client.setCookieStore(myCookieStore);
        client.setTimeout(20 * 1000);
        setHeader(client, false);
        ByteArrayEntity entity = null;
        try {
            entity = new ByteArrayEntity(jsonParams.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try {
//            String fullUrl = DataTools.getServiceAddress(2) + url;
//            client.post(context, fullUrl, entity, "application/json", new AsyncHttpResponseHandler() {
//                @Override
//                public void onSuccess(int i, Header[] headers, byte[] bytes) {
//                    String result = savaFiles(bytes, "HomeCase", filename);
//                    if (!result.equals("")) {
//                        try {
//                            callback.success(requestCode, "/HomeCase/");
//                        } catch (JSONException e) {
//                            e.printStackTrace();
//                            callback.fail(requestCode, i, "附件下载失败:" + result);
//                        }
//                    } else {
//                        callback.fail(requestCode, i, "附件下载失败:" + result);
//                    }
//
//                }
//
//                @Override
//                public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
//                    failResult(context, fullUrl, requestCode, callback, i, headers, bytes, throwable);
//                }
//            });
        } catch (Exception e) {
            e.fillInStackTrace();
            NLogger.e(url, e.getMessage());
        }

    }

    public static void uploadFileWithProgress(final Context context, final String fileType, final String url, RequestParams params, final int requestCode, final AsyncCallback2 callback) {
        AsyncHttpClient client = new AsyncHttpClient();
        PersistentCookieStore myCookieStore = new PersistentCookieStore(context);
        client.setCookieStore(myCookieStore);
        client.setTimeout(30 * 1000);
        setHeader(client, false);
        client.post(url, params, new AsyncHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] binaryData) {
                String result = new String(binaryData);
                try {
                    EvalHeadBean bean = JsonAnalysisUtils.getHeadBean(result);
                    if (bean != null) {
                        if (bean.getMsgcode() == 0) {
                            callback.success(fileType, requestCode, bean.getData());
                        } else {
                            callback.fail(fileType, requestCode, -1, bean.getFaileMsg());
                        }
                    } else {
                        callback.fail(fileType, requestCode, -1, "上传失败: " + result);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    NLogger.e(url, e.getMessage());
                    callback.fail(fileType, requestCode, -1, "上传失败: " + e.getMessage());
                }
            }

            @Override
            public void onProgress(long bytesWritten, long totalSize) {
                super.onProgress(bytesWritten, totalSize);
                int count = (int) ((bytesWritten * 1.0 / totalSize) * 100);
                callback.onProgress(fileType, requestCode, count);
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, byte[] bytes, Throwable error) {
                if (!NetUtils.isConnectInternet(context)) {
                    NetUtils.IfNetOff_OpenSetUI(context);
                    String emsg = "您的WLAN和移动网络均未连接！";
                    callback.fail(fileType, requestCode, -1, emsg);
                } else {
                    Log.e("请求失败状态码", statusCode + "");
                    String result = "";
                    JSONObject object = null;
                    if (bytes != null) {
                        result = new String(bytes);
                        try {
                            object = new JSONObject(result);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    callback.fail(fileType, requestCode, -1, getFailure(url, result));
                }
            }
        });
    }


    public static String getFailure(String url, String errmsg) {
        String e_msg = "";
        if (errmsg.contains("TimeoutException"))
            e_msg = "连接服务器超时(30s)";
        else if (errmsg.contains("ConnectException") || errmsg.contains("404")) {
            if (errmsg.contains(":")) {
                e_msg = "无法连接服务器\n"
                        + errmsg.substring(errmsg.indexOf(":") + 1, errmsg.length());
            } else
                e_msg = "无法连接服务器";
        } else if (errmsg.contains("Proxy Error"))
            e_msg = "网络错误";
        else if (!CommonUtils.isChinese(errmsg))
            e_msg = "网络异常, 请检查网络";
        else
            e_msg = errmsg;
        NLogger.e(url, errmsg);
        return e_msg;
    }


    //串接url参数
    public static String setParam(String key, String value) {
        if (value == null) {
            return "&" + key + "=" + "";
        } else {
            return "&" + key + "=" + value;
        }
    }
}
